<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
        }
    </style>
</head>
<body>
    
</body>
</html>
<script>
/* 1.0版 
 * @Date: 2021-05-23 18:23:00
 * @Address: BeiJingTv
 * @Author: Chang.DongDong
 * @cont: 测试架子 加入正则 
 * 国家尚未富强 怎能儿女情长 为实现中华民族伟大复兴的中国梦而努力奋斗!
 * 
 * 1.1版 
 * @Date: 2021-11-15 20:00:00
 * @Address: 雍和宫科技园 
 * @Author: Chang.DongDong
 * @cont: 加入对象  
 * 知不足者好学 学不可以已 
 * 
 * 1.2版 
 * @Date: 2021-12.01 Xx:00:00
 * @Address: 雍和宫科技园 
 * @Author: Chang.DongDong
 * @cont: 加入防抖节流 
 * 
 */

    (function() {
        /*this指向*/
        var root = (typeof self == 'object' && self.self == self && self) ||    //因为我们要通过 this 获得全局对象，然后将 _ 对象，挂载上去。
            (typeof global == 'object' && global.global == global && global) || //在严格模式下，this返回undefined 而不是指向window 注意在ES6中模块脚本自动采用严格模式，不管有没有声明 use strict。 
            this || {};                                                         //this 返回 undefined，代码就会报错                      

        var ArrayProto = Array.prototype;                                       //这步问题，将方法挂载到函数对象上，却没有挂载到函数的原型上昂！返回实例导致无法调用函数对象上的方法 
        var push = ArrayProto.push;
        var _ = function(obj) {     //函数对象(js中函数也是对象)                 //将所有的方法添加至名为_的对象上，然后将该对象挂载到全局对象上  
            if (obj instanceof _) return obj;
            if (!(this instanceof _)) return new _(obj);
            this._wrapped = obj;
        };
        if (typeof exports != 'undefined' && !exports.nodeType) {
            if (typeof module != 'undefined' && !module.nodeType && module.exports) {
                exports = module.exports = _;
            }
            exports._ = _;
        } else {  
            root._ = _;             //之所以不直接 window._ = _ 是因为我们写的是一个工具函数库，不仅要求可以运行在浏览器端，还可以运行在诸如 Node 等环境中。  
        }

        _.VERSION = '0.1';
        var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
        var isArrayLike = function(collection) {
            var length = collection.length;
            return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
        };
        _.each = function(obj, callback) {
            var length, i = 0;
            if (isArrayLike(obj)) {
                length = obj.length;
                for (; i < length; i++) {
                    if (callback.call(obj[i], obj[i], i) === false) {
                        break;
                    }
                }
            } else {
                for (i in obj) {
                    if (callback.call(obj[i], obj[i], i) === false) {
                        break;
                    }
                }
            }
            return obj;
        }
        _.isFunction = function(obj) {
            return typeof obj == 'function' || false;
        };
        _.functions = function(obj) {
            var names = [];
            for (var key in obj) {
                if (_.isFunction(obj[key])) names.push(key);
            }
            return names.sort();
        };

        // 在 _.mixin(_) 前添加自己定义的方法    Write method here start -------------------------------------
        _.reverse = function(string){
             return string.split('').reverse().join('');
        }

        //Array 扁平化  模拟数组扁平化  
        _.set = function(Array){             
            return Array.flat(Infinity)
        }

        //截取栾晓芳  咔嚓
        _.haha = function(string){           
            // xf = /栾晓芳/igm;
            return string.match(/\?data=(.*)/)[1] ;
        }

        // 判断两个对象节点 
        _.isEqual = function(obj1,obj2){      
            if(!obj1 instanceof Object || !obj2 instanceof Object){ /*  判断不是对象  */
                return obj1 === obj2;
            }
            if(Object.keys(obj1).length !== Object.keys(obj2).length){
                return false;
                //Object.keys() 返回一个由对象的自身可枚举属性(key值)组成的数组,判断键值个数是否相等
            }
            for(var attr in obj1){//逐个值进行判断
                if(obj1[attr] instanceof Object && obj2[attr] instanceof Object){
                    return _.isEqual(obj1[attr],obj2[attr]);   //如果值为对象再递归进行判断
                }else if(obj1[attr] !== obj2[attr]){
                    return false;
                }
            }
            return true;
        }

        _.mixin = function(obj) {
            _.each(_.functions(obj), function(name) {
                var func = _[name] = obj[name];
                _.prototype[name] = function() {
                    var args = [this._wrapped];

                    push.apply(args, arguments);

                    return func.apply(_, args);
                }; 
            });
            return _;
        };
        _.mixin(_);
})()

  //测试代码 
   var a = [1,[1,1],1,2,3,4,5]
   console.log(_.set(a))             //  [1, 1, 1, 1, 2, 3, 4, 5]  
   console.log(_.reverse('hello'))    //  olleh  
   console.log(_.haha('?data=精通死页面无敌,想进去大厂')) 


   var obj1={name:'tom',age:{name:'1tt'}};
   var obj2={name:'tom',age:{name:'1trt'}};
   console.log(_.isEqual(obj1,obj2))

   
</script>